<?php
/**
 * SSO SingleSignOn 单点登录组件
 *
 * @author steven.liaoxw 2009.7.30
 * @author seraph.liujb 2009.8.4
 */

class Common_SSO
{
	/**
	 * SSO服务地址
	 * @var string
	 */
	protected $_url = 'http://192.168.10.254:8080/Service/Account';

	/**
	 * ssoTicket登录标识
	 * @var string
	 */
	public $_ssoTicket;

	/**
	 * SSO端ssoTicket存入cookie的名称
	 * @var string
	 */
	public $_ssoTicketName = 'ssoTicket';

	/**
	 * APP端appTicket存入cookie的名称
	 * @var unknown_type
	 */
	public $_appTicketName = 'loginInfo';

	/**
	 * SSO端cookie生存期
	 * @var int
	 */
	public $_ssoCookieTime = 0;

	/**
	 * APP端cookie生存期
	 * @var int
	 */
	public $_appCookieTime = 0;

	/**
	 * 构造方法
	 */
	public function __construct()
	{
	}

	/**
	 * 判断是否登录，该方法一般被APP端调用
	 *
	 * @param string $ssoTicket 请求进行登录状态验证的ssoTicket，一般为首次登录后从返回URL附带的request中获取，默认为空时从APP端cookie中获取
	 * @return boolean
	 */
	public function isLogin($ssoTicket = '')
	{
		//如果ssoTicket为空，则试图从cookie中获取
		if ('' == $ssoTicket) {
			$ssoTicket = $this->getTicket();
		}
		if ('' != $ssoTicket) {
			//生成XML
			$xml  = '<body controller="auth" action="verify" >';
			$xml .= '<ticket>' .$ssoTicket. '</ticket>';
			$xml .= '</body>';
			//注销登录服务
			$result = $this->_doRequest($xml);
//			var_dump($result);exit;
			if ('1' == $result['code']) {
				//设置APP端cookie，ssoTicket
				setcookie($this->_ssoTicketName,$ssoTicket,$this->_appCookieTime,'/');
				//设置APP端cookie，loginInfo
				setcookie($this->_appTicketName,serialize($result),$this->_appCookieTime,'/');
				return true;
			}
			else {
				return false;
			}
		}
		else {
			return false;
		}
	}

	/**
	 * 登录
	 * @param $params
	 * username 登录帐号
	 * password 登录密码
	 * @return array
	 */
	public function login($params, $ssoTicket = '')
	{
		//生成ssoTicket值，产生随机字符串
		if ('' == $ssoTicket) {
			$ssoTicket = md5($params['username'] . '123456' . microtime());
		}
		//生成XML
		$xml  = '<body controller="auth" action="login" >';
		$xml .= '<ticket>' .$ssoTicket. '</ticket>';
		$xml .= '<username>' .$params['username']. '</username>';
		$xml .= '<password>' .$params['password']. '</password>';
//		$xml .= '<uid>' .$params['uid']. '</uid>';
		$xml .= '</body>';
		//发起登录请求
		$result = $this->_doRequest($xml);
//		var_dump($result);exit;
		//设置SSO端cookie中的ticket，为其它APP域名空间而准备
		setcookie($this->_ssoTicketName,$ssoTicket,$this->_ssoCookieTime,"/");
		//为登录成功后，向后继的页面跳转时需要传递ticket值而准备
		$this->_ssoTicket = $ssoTicket;
		return $result;
	}

	/**
	 * 登出
	 * @return array
	 */
	public function logout($ssoTicket = '')
	{
		if ('' == $ssoTicket) {
			$ssoTicket = $this->getTicket();
		}
		//生成XML
		$xml  = '<body controller="auth" action="logout" >';
		$xml .= '<ticket>' .$ssoTicket. '</ticket>';
		$xml .= '</body>';
		//注销登录服务
		$result = $this->_doRequest($xml);
//		var_dump($result);exit;
		//清空APP端cookie中的ssoTicket
		setcookie($this->_ssoTicketName,'',-1,"/");
		//清空APP端cookie中的appTicket
		setcookie($this->_appTicketName,'',-1,"/");
		return $result;
	}

	/**
	 * 获取ticket
	 * @return string
	 */
	public function getTicket()
	{
		if ('' != $this->_ssoTicket) {
			return $this->_ssoTicket;
		}
		if (null == $_COOKIE[$this->_ssoTicketName]) {
			$ticket = '';
		}
		else {
			$ticket = $_COOKIE[$this->_ssoTicketName];
		}
		return $ticket;
	}

	/**
	 * 设置ticket
	 * @param $ticket
	 * @return void
	 */
	public function setTicket($ticket)
	{
		$this->_ssoTicket = $ticket;
		setcookie($this->_ssoTicketName,$ticket,$this->_appCookieTime,'/');
	}

	/**
	 * 帐户注册
	 * @param $params
	 * username 帐户名称
	 * password 密码
	 * domain 域名空间
	 * createTime 注册时间
	 * active 激活状态
	 * email 邮箱地址
	 * @return array
	 */
	public function create($params)
	{
		//生成XML
		$xml  = '<body controller="register" action="create" >';
		$xml .= '<username>' .$params['username']. '</username>';
		$xml .= '<password>' .$params['password']. '</password>';
		$xml .= '<domain>' .$params['domain']. '</domain>';
		$xml .= '<createTime>' .$params['createTime']. '</createTime>';
		$xml .= '<active>' .$params['active']. '</active>';
		$xml .= '<email>' .$params['email']. '</email>';
		$xml .= '</body>';
		//注册
		$result = $this->_doRequest($xml);
		return $result;
	}
	
	/**
	 * 注销帐户
	 * @param $params
	 * username 帐户名称
	 * @return array
	 */
	public function delete($params)
	{
		$xml  = '<body controller="register" action="delete" >';
		$xml .= '<username>' .$params['username']. '</username>';
		$xml .= '</body>';
		$result = $this->_doRequest($xml);
		return $result;
	}

	/**
	 * 执行请求
	 * @param $xml
	 * @param $method
	 * @return array
	 */
	public function _doRequest($xml, $method = Zend_Http_Client::POST)
	{
		$client = new Zend_Http_Client($this->_url);
		$client->setMethod($method);
		$client->setRawData($xml);
		$response = $client->request();
		$result = Zend_Json::decode(Zend_Json::fromXml($response->getBody()));
		return $result['body'];
	}



	public function encode($array)
	{
		return $this->passportEncrypt($this->passportEncode($array));
	}

	/**
	 * 解密字符串，成功返回数组，不成功返回 false
	 *
	 * @param string $str
	 * @return array
	 */
	public  function decode($string)
	{
		try {
			echo $string;
			$string = $this -> passportDecrypt($string);
			$info = split('&',$string);
			foreach ($info as $val) {
				$v = split('=',$val);
				@$auth[$v[0]] = $v[1];
			}
			return $auth;
		} catch (Exception $e){
			return FALSE;
		}
	}

	/**
	 * 数组编码
	 * @param    array $array    数组
	 * @return   string
	 */
	private function passportEncode($array)
	{
		$arrayenc = array();
		foreach($array as $key => $val) {
			$arrayenc[] = $key.'='.urlencode($val);
		}
		return implode('&', $arrayenc);
	}

	/**
	 * 字符串加密
	 * @param    string $txt    字符串
	 * @return   string
	 */
	private function passportEncrypt($txt)
	{
		srand((double)microtime() * 1000000);
		$encrypt_key = md5(rand(0, 32000));
		$ctr = 0;
		$tmp = '';
		for($i = 0;$i < strlen($txt); $i++) {
			$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
			$tmp .= $encrypt_key[$ctr].($txt[$i] ^ $encrypt_key[$ctr++]);
		}
		return base64_encode($this -> passportKey($tmp, $this -> _keys));
	}

	/**
	 * 字符串解密
	 * @param    string $txt    字符串
	 * @return   string
	 */
	private function passportDecrypt($txt)
	{
		$txt = $this -> passportKey(base64_decode($txt), $this -> _keys);
		$tmp = '';
		for($i = 0;$i < strlen($txt); $i++) {
			$md5 = $txt[$i];
			@$tmp .= $txt[++$i] ^ $md5;
		}
		return $tmp;
	}

	/**
	 * 处理keys
	 * @param    string $txt    字符串
	 * @param    string $encrypt_key    编码字符串
	 * @return   string
	 */
	private function passportKey($txt, $encrypt_key)
	{
		$encrypt_key = md5($encrypt_key);
		$ctr = 0;
		$tmp = '';
		for($i = 0; $i < strlen($txt); $i++) {
			$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
			$tmp .= $txt[$i] ^ $encrypt_key[$ctr++];
		}
		return $tmp;
	}
}
